﻿using System.Collections.Generic;
using UnityEngine;

namespace GameToolkit
{
    public partial class ActorBehaviour
    {
        /// <summary>
        /// 输入数据
        /// </summary>
        public interface IInputAction
        {
            bool IsHolding { get; }
        }

        public interface IInputAction<out TValue> : IInputAction
        {
            TValue GetInputValue();
        }

        /// <summary>
        /// 角色控制中的状态定义
        /// </summary>
        public enum EPosture
        {
            // 站立
            Standing,
            // 下落
            Falling,
            // 飞行中
            Flying,
            // 游泳
            Swimming,
            // 潜水
            Diving,
            // 驾驶，骑乘
            Riding,
        }

        /// <summary>
        /// 角色行为组件
        /// </summary>
        public interface IFeature
        {
            void OnFeatureEnable(ActorBehaviour actor);
            void OnFeatureDisable(ActorBehaviour actor);
        }

        /// <summary>
        /// 角色姿态实现
        /// </summary>
        public interface IPoseture : IFeature
        {
            Vector3 Velocity { get; }
            EPosture PosetureState { get; }
            void OnEnter(Vector3 initVelocity, EPosture initPoseture);
            void OnExit();
            void OnUpdatePoseture(float deltaTime);
        }

        /// <summary>
        /// 默认 poseture
        /// </summary>
        public interface IDefaultPoseture : IPoseture
        {
            // 排列顺序（较小值优先作为默认状态）
            int ExecutionOrder { get; }
        }

        /// <summary>
        /// 控制器接口
        /// </summary>
        public interface IController : IFeature
        {
            /// <summary>
            /// 执行优先级（由小到大对应优先级由低到高）
            /// </summary>
            int Priority { get; }
            IInputAction GetInputAction(Object descriptor);
            void OnControlling(float deltaTime);
            void OnActivate();
            void OnDeactivate();
        }

        /// <summary>
        /// 主动能力
        /// </summary>
        public interface IAbility : IFeature
        {
            /// <summary>
            /// 激活能力
            /// </summary>
            void OnActivate();
            void OnDeactivate();
            /// <summary>
            /// 是否可被中断
            /// </summary>
            /// <param name="interruptSource"></param>
            /// <returns></returns>
            bool IsInterruptable(IAbility interruptSource);
            /// <summary>
            /// 执行能力更新，
            /// </summary>
            /// <param name="deltaTime"></param>
            /// <returns>如果能力执行结束，则返回 false, 否则返回 true</returns>
            bool OnUpdateAbility(float deltaTime);
        }

        // 能力覆盖
        public interface IOverriderAbility : IAbility { }

        // 能力叠加
        public interface IAdditionalAbility : IAbility { }

        /// <summary>
        /// CD 计时器
        /// </summary>
        public interface IAbilityWithCD : IAbility
        {
            /// <summary>
            /// CD 进度（0表示计时结束，1表示满cd计时）
            /// </summary>
            float Progress { get; }
            /// <summary>
            /// CD Tick
            /// </summary>
            /// <param name="deltaTime"></param>
            void OnCDTick(float deltaTime);
        }

        /// <summary>
        /// 可输入数据
        /// </summary>
        public interface IAbilityInput
        {
            Object Descriptor { get; }
            bool IsDown { get; }
            bool IsUp { get; }
            bool IsHolding { get; }
            bool GetValue<T>(out T value);
        }

        /// <summary>
        /// 实现该接口以获取输入信息
        /// </summary>
        public interface IAbilityWithInput : IAbility
        {
            /// <summary>
            /// 执行输入优先级（由小到大对应优先级由低到高）
            /// </summary>
            int Priority { get; }
            /// <summary>
            /// 绑定输入信息
            /// </summary>
            /// <param name="inputs"></param>
            void GetUsedInputs(ICollection<Object> inputsDescriptor);
            /// <summary>
            /// 输入操作，如果返回 true, 则该输入不再向下传递，否则输入将继续传递到下层行为
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            bool ExecuteInput(IAbilityInput input);
        }

        ///// <summary>
        ///// 重置坐标回调
        ///// </summary>
        //public interface IPositionWrapper
        //{
        //    void WrapPosition(Vector3 position);
        //}
    }
}
